package datamining.sequence;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import datamining.sequence.ItemSet;
import datamining.common.Cloneable;

public class Sequence<ItemType> implements Cloneable<Sequence<ItemType>>,
		Comparable<Sequence<ItemType>> {
	/**
	 * 
	 */
	private List<ItemSet<ItemType>> itemSets = new ArrayList<ItemSet<ItemType>>();
	public int idx;

	public Sequence() {
		super();
	}

	public Sequence(List<ItemSet<ItemType>> itemSets) {
		super();
		setItemSets(itemSets);
	}

	public void append(ItemSet<ItemType> itemSet) {
		itemSets.add(itemSet);
	}

	public void append(ItemType item, boolean newSet) {
		if(newSet || itemSets.size() == 0){
			ItemSet<ItemType> newItemSet = new ItemSet<ItemType>();
			newItemSet.add(item);
			itemSets.add(newItemSet);
		}else{
			itemSets.get(itemSets.size()-1).add(item);
		}
		
	}

	@Override
	public int compareTo(Sequence<ItemType> o) {
		Iterator<ItemSet<ItemType>> thisIter = itemSets.iterator();
		Iterator<ItemSet<ItemType>> anotherIter = o.getItemSets()
				.iterator();

		while (thisIter.hasNext()) {
			if (!anotherIter.hasNext()) {
				return 1;
			}

			ItemSet<ItemType> i1 = thisIter.next();
			ItemSet<ItemType> i2 = anotherIter.next();

			int diff = i1.compareTo(i2);
			if (diff != 0) {
				return diff;
			}
		}

		if (itemSets.size() < o.getItemSets().size()) {
			return -1;
		}

		return 0;
	}

	public boolean equals(Sequence<ItemType> obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Sequence<ItemType> other = (Sequence<ItemType>) obj;
		if (itemSets == null) {
			if (other.itemSets != null)
				return false;
		} else if (!itemSets.equals(other.itemSets))
			return false;
		return true;
	}

	public List<ItemSet<ItemType>> getItemSets() {
		return itemSets;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((itemSets == null) ? 0 : itemSets.hashCode());
		return result;
	}

	public void setItemSets(List<ItemSet<ItemType>> itemSets) {
		if (itemSets == null) {
			this.itemSets = new ArrayList<ItemSet<ItemType>>();
		} else {
			this.itemSets = itemSets;
		}
	}

	@Override
	public String toString() {
		String seq_str = "";
		seq_str += "<";

		for (ItemSet<ItemType> itemSet : itemSets)
			seq_str += " (" + itemSet.toString() + ")";

		seq_str += " >";
		return seq_str;

	}

	public HPSequence<ItemType> toHPSequence() {
			return new HPSequence<ItemType>(this);
	}

	public Sequence<ItemType> clone() {
		List<ItemSet<ItemType>> itemSets_copy = new ArrayList<ItemSet<ItemType>>();

		for (ItemSet<ItemType> itemSet : itemSets) {
			itemSets_copy.add(itemSet.clone());
		}

		return new Sequence<ItemType>(itemSets_copy);
	}
}
